package com.zmx.common.common.service.mapper;

import com.zmx.common.common.dto.BaseDto;
import com.zmx.common.common.entitys.BaseEntity;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

/**
 * @Description: 数据类型转换抽象基类-用于数据传输对象和实体bean的相互转换
 * @ClassName: BaseMapper
 * @Author zhaomxr
 * @Date 2021-10-11 15:30
 */
@Slf4j
public abstract class BaseMapper<TEntity extends BaseEntity, TDto extends BaseDto> {

    /**
     * 实体bean -> 数据传输对象
     *
     * @param entity 实体bean
     * @return TDto 数据传输对象
     */
    public abstract TDto entityToDto(TEntity entity);

    /**
     * 实体bean -> 数据传输对象
     *
     * @param entitys 实体bean列表
     * @return 数据传输对象列表
     */
    public abstract List<TDto> entityToDtos(List<TEntity> entitys);

    /**
     * 数据传输对象 -> 实体bean
     *
     * @param dto 数据传输对象
     * @return 实体bean
     */
    public abstract TEntity dtoToEntity(TDto dto);

    /**
     * 数据传输对象 -> 实体bean
     *
     * @param dtos 数据传输对象列表
     * @return 实体bean列表
     */
    public abstract List<TEntity> dtoToEntitys(List<TDto> dtos);


    public TEntity entityFromId(Long id) {
        Class<?> aClass = getClass();
        while (aClass.getSuperclass() != null && !BaseMapper.class.equals(aClass.getSuperclass())) {
            aClass = aClass.getSuperclass();
        }

        Type type = ((ParameterizedType) aClass.getGenericSuperclass()).getActualTypeArguments()[0];
        TEntity entity = null;
        try {
            entity = (TEntity) Class.forName(((Class) type).getName()).getConstructor().newInstance();
        } catch (ClassNotFoundException e) {
            log.error(e.getMessage(), e);
        } catch (NoSuchMethodException e) {
            log.error(e.getMessage(), e);
        } catch (IllegalAccessException e) {
            log.error(e.getMessage(), e);
        } catch (InstantiationException e) {
            log.error(e.getMessage(), e);
        } catch (InvocationTargetException e) {
            log.error(e.getMessage(), e);
        }
        if (entity != null) {
            entity.setId(id);
        }
        return entity;
    }
}
